package org.black.missedCall2.reply.content;

import java.util.Arrays;
import java.util.HashSet;

import org.black.missedCall2.reply.sqlite.ReplyOpenHelper;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

public class ReplyContentProvider extends ContentProvider {
	private static final int MISSED_CALL_REPLY = 1;
	private static final int MISSED_CALL_REPLY_ID = 2;

	private ReplyOpenHelper replyOpenHelper = null;
	private static final UriMatcher sURIMatcher = new UriMatcher(
			UriMatcher.NO_MATCH);
	static {
		sURIMatcher.addURI(ReplyContentProviderMetaData.AUTHORITY, ReplyContentProviderMetaData.BASE_PATH, MISSED_CALL_REPLY);
		sURIMatcher.addURI(ReplyContentProviderMetaData.AUTHORITY, ReplyContentProviderMetaData.BASE_PATH + "/#", MISSED_CALL_REPLY_ID);
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		int match = sURIMatcher.match(uri);
		SQLiteDatabase database = this.replyOpenHelper.getWritableDatabase();
		int result = 0;
		switch (match) {
		case MISSED_CALL_REPLY:
			result = database.delete(ReplyOpenHelper.TABLE_REPLY, selection,
					selectionArgs);
			break;
		case MISSED_CALL_REPLY_ID:
			String id = uri.getLastPathSegment();
			if (TextUtils.isEmpty(selection)) {
				result = database.delete(ReplyOpenHelper.TABLE_REPLY,
						ReplyOpenHelper.COLUMN_ID + "=" + id, null);
			} else {
				result = database.delete(ReplyOpenHelper.TABLE_REPLY,
						ReplyOpenHelper.COLUMN_ID + "=" + id + selection,
						selectionArgs);
			}
		default:
			throw new IllegalArgumentException("Unknown URI: " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return result;
	}

	@Override
	public String getType(Uri uri) {
		int match = sURIMatcher.match(uri);
		switch (match) {
		case MISSED_CALL_REPLY:
			return ReplyContentProviderMetaData.AUTHORITY + "/" + ReplyContentProviderMetaData.BASE_PATH;
		case MISSED_CALL_REPLY_ID:
			return ReplyContentProviderMetaData.AUTHORITY + "/" + ReplyContentProviderMetaData.BASE_PATH;
		default:
			return null;
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		int match = sURIMatcher.match(uri);
		SQLiteDatabase database = this.replyOpenHelper.getWritableDatabase();
		long id = 0;
		switch (match) {
		case MISSED_CALL_REPLY:
			id = database.insert(ReplyOpenHelper.TABLE_REPLY, null, values);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI: " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return Uri.parse(ReplyContentProviderMetaData.BASE_PATH + "/" + id);
	}

	@Override
	public boolean onCreate() {
		this.replyOpenHelper = new ReplyOpenHelper(getContext(), null, null, 1);

		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
		checkColumns(projection);

		queryBuilder.setTables(ReplyOpenHelper.TABLE_REPLY);

		int match = sURIMatcher.match(uri);
		switch (match) {
		case MISSED_CALL_REPLY:
			break;
		case MISSED_CALL_REPLY_ID:
			queryBuilder.appendWhere(ReplyOpenHelper.COLUMN_ID + "="
					+ uri.getLastPathSegment());
		default:
			throw new IllegalArgumentException("Unknown uri: " + uri);
		}
		SQLiteDatabase database = this.replyOpenHelper.getWritableDatabase();
		Cursor cursor = queryBuilder.query(database, projection, selection,
				selectionArgs, null, null, sortOrder);
		cursor.setNotificationUri(getContext().getContentResolver(), uri);
		return cursor;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		int match = sURIMatcher.match(uri);
		SQLiteDatabase database = this.replyOpenHelper.getWritableDatabase();
		int result = 0;
		switch (match) {
		case MISSED_CALL_REPLY:
			result = database.delete(ReplyOpenHelper.TABLE_REPLY, selection,
					selectionArgs);
			break;
		case MISSED_CALL_REPLY_ID:
			String id = uri.getLastPathSegment();
			if (TextUtils.isEmpty(selection)) {
				result = database.update(ReplyOpenHelper.TABLE_REPLY, values,
						selection, selectionArgs);
			} else {
				result = database.update(ReplyOpenHelper.TABLE_REPLY, values,
						ReplyOpenHelper.COLUMN_ID + "=" + id + " AND "
								+ selection, selectionArgs);
			}
		default:
			throw new IllegalArgumentException("Unknown URI: " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return result;
	}

	private void checkColumns(String[] projection) {
		String[] available = { ReplyOpenHelper.COLUMN_ID,
				ReplyOpenHelper.COLUMN_LISTEN_FOR,
				ReplyOpenHelper.COLUMN_MESSAGE,
				ReplyOpenHelper.COLUMN_RESPONSE_TO,
				ReplyOpenHelper.COLUMN_SHOULD_REPLY };
		if (projection != null) {
			HashSet<String> requestedColumns = new HashSet<String>(
					Arrays.asList(projection));
			HashSet<String> availableColumns = new HashSet<String>(
					Arrays.asList(available));
			// Check if all columns which are requested are available
			if (!availableColumns.containsAll(requestedColumns)) {
				throw new IllegalArgumentException(
						"Unknown columns in projection");
			}
		}
	}

}
